import os
import sys
from pathlib import Path
import requests
from tqdm import tqdm
import zipfile
import tarfile
import py7zr
import patoolib

# Import configuration from config.py
try:
    from config import software_dict as software_config
except ImportError:
    print("Error: config.py not found or invalid format")
    sys.exit(1)

def download_file_with_progress(url, save_path):
    """Download with progress bar"""
    print(f"\nDownloading {url}...")
    response = requests.get(url, stream=True)
    response.raise_for_status()
    
    total_size = int(response.headers.get('content-length', 0))
    block_size = 8192
    
    with tqdm(total=total_size, unit='iB', unit_scale=True) as progress_bar:
        with open(save_path, 'wb') as f:
            for data in response.iter_content(block_size):
                progress_bar.update(len(data))
                f.write(data)
    
    if total_size != 0 and progress_bar.n != total_size:
        raise Exception("Download incomplete")
    
    print(f"Saved to {save_path}")

def detect_archive_type(filename):
    """Detect archive type from filename"""
    filename = filename.lower()
    if filename.endswith('.zip'):
        return 'zip'
    elif filename.endswith('.tar.gz') or filename.endswith('.tgz'):
        return 'tar.gz'
    elif filename.endswith('.rar'):
        return 'rar'
    elif filename.endswith('.7z'):
        return '7z'
    return None

def extract_archive(archive_path, extract_to, archive_type=None):
    """Extract various archive formats with progress"""
    if not archive_type:
        archive_type = detect_archive_type(str(archive_path))
    
    print(f"\nExtracting {archive_path.name} to {extract_to}...")
    extract_to = Path(extract_to)
    extract_to.mkdir(parents=True, exist_ok=True)
    
    try:
        if archive_type == 'zip':
            with zipfile.ZipFile(archive_path, 'r') as zip_ref:
                for file in tqdm(zip_ref.infolist(), unit='files'):
                    zip_ref.extract(file, extract_to)
        
        elif archive_type == 'tar.gz':
            with tarfile.open(archive_path, 'r:gz') as tar_ref:
                members = tar_ref.getmembers()
                for member in tqdm(members, unit='files'):
                    tar_ref.extract(member, extract_to)
        
        elif archive_type in ('rar', '7z'):
            patoolib.extract_archive(
                str(archive_path),
                outdir=str(extract_to),
                interactive=False,
                program='unrar' if archive_type == 'rar' else '7z'
            )
            print("Extraction complete (using external tool)")
        
        else:
            raise ValueError(f"Unsupported archive format: {archive_type}")
    
    except Exception as e:
        print(f"Extraction failed: {str(e)}")
        raise
    
    print("Extraction completed successfully")

def main():
    # Check for required packages
    try:
        import tqdm
        import py7zr
        import patoolib
    except ImportError:
        print("Installing required packages...")
        import subprocess
        subprocess.check_call([sys.executable, "-m", "pip", "install", "tqdm", "py7zr", "patool", "unrar"])
    
    # Process each software in config
    for software_name, config in software_config.items():
        print(f"\nProcessing {software_name}...")
        
        try:
            # Setup paths
            save_dir = Path(config['save_dir'])
            archive_path = save_dir.parent / Path(config['download_url']).name
            
            # Download
            download_file_with_progress(config['download_url'], archive_path)
            
            # Extract
            extract_archive(
                archive_path,
                save_dir.parent,
                config.get('archive_type')
            )
            
            print(f"\n{software_name} installation completed successfully!")
        
        except Exception as e:
            print(f"\nError installing {software_name}: {str(e)}")
            continue

if __name__ == "__main__":
    main()